<?php
namespace bee;
/**
 *
 * @author dy <damir.zelenika@gmail.com>
 * @version $Id: version.php
 *
 */
class rowSet extends object
{ private $__sqt;
  private $__table;
  private $__daoRow;
  private $__param           = array();
  private $__paramType      = array();
  private $__stmt;
  private $DAOprops = array();//('conn', 'sys_table');//'limitFrom', 'limitTo');
  private $__limitFrom;
  private $__limitTo;
  public $num_rows;
  private $__fetchetRows;
	/**
	 *
	 * @var db
	 */
  private $__conn;

  function __construct(DAO $daoRow, afterWhere $afterWhere = null, $limitFrom = 0, $limitTo = 0, &$echoSQT = "")
  { $this->__daoRow = $daoRow;
  	$this->__table = $daoRow->geSysTable();
  	$this->__conn = $daoRow->getConn();
  	$this->__limitFrom    = ($limitFrom < 0 ? 0 : $limitFrom);
  	$this->__limitTo      = ($limitTo < 0 ? 0 : $limitTo);

  	$where_refl = new \ReflectionClass(get_class($daoRow));
  	$cls_props = $where_refl->getProperties(\ReflectionProperty::IS_PUBLIC);
  	$query_arr = array("1=1");
  	$param_array = array();

  	foreach ($cls_props as $prop)
  	{ if(!empty($daoRow->{$prop->name}) && !in_array($prop->name, $this->DAOprops))
  	  {	$query_arr[$prop->name] = $this->__conn->__NAME_OPEN . $prop->name . $this->__conn->__NAME_CLOSE . "= :" . $prop->name ;// . $daoRow->prepareSQL($daoRow->{$prop->name}, true);
  		  $param_array[":" .$prop->name] = $daoRow->{$prop->name};
  	  }
  	}
  	//$this->__sqt = "SELECT * FROM " . $this->__conn->__NAME_OPEN . strtoupper($this->__table) . $this->__conn->__NAME_CLOSE . " WHERE ". strtoupper(implode(" AND ", $query_arr) . " " . ($afterWhere ? $afterWhere->text : ""));
  	$this->__sqt = "SELECT * FROM " . $this->__conn->__NAME_OPEN . $this->__table . $this->__conn->__NAME_CLOSE . " WHERE ". implode(" AND ", $query_arr) . " " . ($afterWhere ? $afterWhere->text : "");
  	//echo( "<br />$this->__sqt");
/**
 * @todo kad je moguće trebalo bi koristiti PDO::CURSOR_FWDONLY jer je brži
 * (mislim kad nema $limitFrom a)
 */
  	try
  	{
      $this->__stmt = $this->__conn->prepare($this->__sqt, array(\PDO::ATTR_CURSOR => \PDO::CURSOR_SCROLL));
  	  foreach ($cls_props as $prop)
      { if(!empty($daoRow->{$prop->name}) && !in_array($prop->name, $this->DAOprops))
        { $this->__stmt->bindParam(":" . $prop->name, $daoRow->{$prop->name}, isset($this->param_type[$prop->name])? $this->param_type[$prop->name] : \PDO::PARAM_INT );
        }
      }
      if($afterWhere)
      { $ps = $afterWhere->getParams();
    	  foreach ($ps as $key => $val)
    	  { $this->__param[$key] = $val;
    	    $this->__paramType[$key] = $afterWhere->getType($key);
    	    $this->__stmt->bindValue($key, $this->__param[$key], $this->__paramType[$key]) . "+";;//$daoRow->{$afterWhere->getParam($key)});//, isset($afterWhere->get_type($key))? $afterWhere->get_type($key) : \PDO::PARAM_INT );
    	  }
      }
      //echo $this->__sqt;
  	  $this->__stmt->execute();

    	$echoSQT = $this->__sqt;
    	$this->num_rows = $this->__stmt->rowCount();
    	if($this->__limitFrom > 1)
    	{ for($i = 0; $i < $this->__limitFrom - 1; $i++)
    	  { $this->__stmt->fetch(\PDO::FETCH_ASSOC, \PDO::FETCH_ORI_NEXT);// mysql problem
    	  }
    	}
  	} catch(\PDOException $e)
  	{ echo "(rowSet.php line 80)Error executig " . $this->__sqt . "<br />\n";
  	  //throw $e;
  	}
  }

	public function limitFrom()
	{  return $this->__limitFrom;
	}
	public function limitTo()
	{  return $this->__limitTo;
	}
	/**
	 *
	 * @todo removed reference &
	 * @param unknown_type $row_nr
	 */
	public function getRow(DAO $daoRow = NULL, $row_nr = -1)//public function getRow(DAO &$daoRow = NULL, $row_nr = -1)
	{	$class_name = get_class($this->__daoRow);
		if(!$daoRow)
		{	$daoRow = new $class_name();
		}
		//echo "$class_name<br />";
		$this->__stmt->setFetchMode(\PDO::FETCH_INTO, $daoRow);
		if($row_nr == -1)
		{ if(!$this->__limitTo || $this->__fetchetRows <= $this->__limitTo - ($this->__limitFrom ?: 1))
      { if($Row = $this->__stmt->fetch(\PDO::FETCH_INTO, \PDO::FETCH_ORI_NEXT))
        { $this->__fetchetRows++;
          $daoRow = $Row;
          return $daoRow;
        }
      }
		} else if($row_nr == 1)
		{ if(!$this->__limitFrom)
		  { if($Row = $this->__stmt->fetch(\PDO::FETCH_INTO, \PDO::FETCH_ORI_FIRST))
        { $this->__fetchetRows = $row_nr;
          $daoRow = $Row;
          return $daoRow;
        }
		  }
		} else
		{ if($row_nr >= $this->__limitFrom && (!$this->__limitTo || $row_nr < $this->__limitTo))
		  { if($Row = $this->__stmt->fetch(\PDO::FETCH_INTO, \PDO::FETCH_ORI_ABS, $row_nr))
        { $this->__fetchetRows = $row_nr;
          $daoRow = $Row;
          return $daoRow;
        }
      }
		}
		return false;
	}
/**
 *
 * Enter description here ...
 * @param string $field
 * @param string $key
 * @return array
 */
	public function getList($field = "value", $key = "")
	{	$retArr = array();
		if(!$key)
		{	$key = "id";
		}
		if($this->getRow($this->__daoRow, 1))
		{ do
		  {	$retArr[$this->__daoRow->$key] = $this->__daoRow->$field;
		  } while ($this->getRow($this->__daoRow));
		}
		return  $retArr;
	}

	public function getAutoComplete($valueFieldName = "value", $keyFieldName = "id", $getAsJsonString = true)
	{
    $retArr = array();
	  if($this->getRow($this->__daoRow, 1))
	  {
	    do
	    {
	      $retArr[] = array("id" => $this->__daoRow->$keyFieldName, "value" => $this->__daoRow->$valueFieldName);
	    } while ($this->getRow($this->__daoRow));
	  }
	  if($getAsJsonString)
	  { return json_encode($retArr);
	  } else
	  { return $retArr;
	  }
	}

	public function getTable()
	{	$retArr = array();
	  if($this->getRow($this->__daoRow, 1))
	  { do
	    { $arr_row = array();
	      $retArr[] = clone $this->__daoRow;
	    } while ($this->getRow($this->__daoRow));
	  }
	  return  $retArr;
	}

	public function deleteByDaoRow()
	{	$count = 0;
	  if($this->getRow($this->__daoRow, 1))
	  { do
	    { $this->__daoRow->DELETE();
	      $count++;
	    } while ($this->getRow($this->__daoRow));
	    return $count;
	  }

	}

	public function getSum($field = "value")
	{	mssql_data_seek($this->rs, 0);//???????????????
		$sum = 0;
		while ($this->getRow($row))
		{	$sum += $row->$field;
		}
		return  $sum;
	}

	public function getMax($field = "value")
	{	mssql_data_seek($this->rs, 0);//????????????
		$max = "";
		if($this->getRow($row))
		{	$max = $row->$field;
			while ($this->getRow($row))
			{	if($row->$field > $max)
				{	$max = $row->$field;
				}
			}
		}
		return  $max;
	}

	public function getMin($field = "value", $no_nulls = true)
	{	mssql_data_seek($this->rs, 0);//????????
		$min = "";
		if($this->getRow($row))
		{	$min = $row->$field;
			while ($this->getRow($row))
			{	if(!$no_nulls || $row->$field)
				if($row->$field < $min)
				{	$min = $row->$field;
				}
			}
		}
		return  $min;
	}

	public function getArray()
	{	$retArr = array();
    if($this->getRow($this->__daoRow, 1))
    { do
	    { $arr_row = array();
	      foreach($this->__daoRow as $key => $val)
	      { $arr_row[$key] = $val;
	      }
	      $retArr[] = $arr_row;

	    } while ($this->getRow($this->__daoRow));
    }
		return  $retArr;
	}
	/**
	 * @todo obavezno dokumentirati
	 * @param array $callBacks
	 * @return unknown_type
	 */
  public function getArrayCallback(array $callBacks)
  { $retArr = array();
    if($this->getRow($this->__daoRow, 1))
    { do
      { $arr_row = array();
        foreach($this->__daoRow as $key => $value)
        { $ccall = $callBacks;
          if(isset($callBacks[$key]))
	        { foreach ($ccall[$key]["params"] as $pkey => &$pvalue)
	          { if($pvalue == "__field__")
	            { $pvalue = $value;
	            }
	          }
	          $value = call_user_func_array($ccall[$key]["function"], $ccall[$key]["params"]);
	          //echo "$value<br />";
	        }
	        if(!is_array($value))
	        {  $arr_row[$key] = $value;
	        }
        }
        $retArr[] = $arr_row;

      } while ($this->getRow($this->__daoRow));
    }
    return  $retArr;
  }

	public function getTableName()
	{	return $this->__table;
	}

	public function getDAORow()
	{	return $this->__daoRow;
	}

	public function getSql()
	{ return $this->__sqt;
	}

}
